import javax.swing.*;
import java.awt.*;
import java.util.*;

public class HElevator implements Runnable {

    private int id;             //电梯的唯一标识
    private int state;          //有运行、维修这两种状态
   // private int groupId;        //所在组id
    private int currentFloor;   //所在楼层
    private Random random;      //产生随机上下电梯人数
    private int[] randomCmd;    //存储电梯去该层的内呼或外呼命令（内呼为0，外呼为1）
    private int maxCmd;         //层数最高的一个命令
    private int minCmd;         //层数最低的一个命令
    private int lastCmd;        //最终要到达的层数

    public int getCurrentFloor() {
        return currentFloor;
    }

    public void setCurrentFloor(int currentFloor) {
        this.currentFloor = currentFloor;
    }

    public int getLastCmd() {
        return lastCmd;
    }

    public void setLastCmd(int lastCmd) {
        this.lastCmd = lastCmd;
    }

    public int[] getRandomCmd() {
        return randomCmd;
    }

    private int direction;      //电梯运行方向（1表示上行，-1表示下行，0表示停止）
    private int countPeople;    //电梯上总人数
    private boolean doorClose;  //门是否关上

    protected JLabel[] elevatorPanel;   //电梯面板

    public final static int OVER_WEIGHT = 13;
    //运行方向
    public final static int UP = 1;
    public final static int PAUSED = 0;
    public final static int DOWN = -1;
    //电梯状态
    public final static int RUN = 1;
    public final static int REPAIR = 2;

    public HElevator(int i) {
        id = i;
        state = HElevator.RUN;
        direction = HElevator.PAUSED;
        currentFloor = 1;
        countPeople = 0;

        doorClose = true;

        elevatorPanel = new JLabel[20];

        randomCmd = new int[20];
        maxCmd = minCmd = lastCmd = 1;
        random = new Random();
    }

    public int getCountPeople() {
        return countPeople;
    }

    public void run(){

        while(true) {
            try
            {
                Thread.sleep(100);
            } catch (InterruptedException e)
            {
                e.printStackTrace();
            }
            if(state == RUN) {
                if (direction == UP || direction == DOWN) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    direction = PAUSED;
                }

                if (lastCmd > currentFloor) {
                    setDirection(UP);
                    moveUp();
                    setDirection(PAUSED);
                }
                else if (lastCmd < currentFloor) {
                    setDirection(DOWN);
                    moveDown();
                    setDirection(PAUSED);
                }
            }
            else {
                setDirection(PAUSED);
            }
        }
    }

    public void setDirection(int direction) {
        this.direction = direction;
    }

    public int getDirection() {
        return direction;
    }

    public void setRandomCmd(int floor, int cmd) {
        randomCmd[floor - 1] = cmd;
    }

    public void setState(int state) { this.state = state; }

    public int getState() {
        return state;
    }

    public JLabel[] getElevatorPanel() {
        return elevatorPanel;
    }

    public void openDoor() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("*******************************");
        System.out.println("电梯开门");
        doorClose = false;
    }

    public void closeDoor() {
        try {
            Thread.sleep(500);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("电梯关门");
        System.out.println("*******************************");
        doorClose = true;

    }

    public void moveUp() {

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

       // if ((currentFloor == 1 && direction == HElevator.DOWN) || (currentFloor == 20 && direction == HElevator.UP))
        //    setDirection(HElevator.PAUSED);

        //if(currentFloor == 20 && direction == HElevator.UP)
         //   setDirection((HElevator.DOWN));

        elevatorPanel[currentFloor].setOpaque(true);
        elevatorPanel[currentFloor].setBackground(Color.BLACK);
        elevatorPanel[currentFloor - 1].setOpaque(false);
        elevatorPanel[currentFloor - 1].setBackground(Color.WHITE);
        currentFloor++;

        //判断当前楼层是否有内呼请求
        if(randomCmd[currentFloor-1] == 1) {
            leaveElevator();
        }

        //判断当前楼层是否有外呼请求
        if(randomCmd[currentFloor-1] == 2) {
           enterElevator();
        }

        //elevatorPanel[currentFloor - 2].setOpaque(true);
        //elevatorPanel[currentFloor - 2].setBackground(Color.BLACK);
        //elevatorPanel[currentFloor - 1].setOpaque(false);
        //elevatorPanel[currentFloor - 1].setBackground(Color.WHITE);
        //currentFloor--;
        //}
    }

    public void moveDown() {

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        //if(currentFloor == 1 && direction == HElevator.DOWN)
        //   setDirection((HElevator.UP));

        elevatorPanel[currentFloor - 2].setOpaque(true);
        elevatorPanel[currentFloor - 2].setBackground(Color.BLACK);
        elevatorPanel[currentFloor - 1].setOpaque(false);
        elevatorPanel[currentFloor - 1].setBackground(Color.WHITE);
        currentFloor--;

        //判断当前楼层是否有内呼请求
        if(randomCmd[currentFloor-1] == 1) {
            leaveElevator();
        }

        //判断当前楼层是否有外呼请求
        if(randomCmd[currentFloor-1] == 2) {
            enterElevator();
        }
    }

    //随机产生进入电梯的人数，若超重则提示
    public void enterElevator() {
        openDoor();
        int arrivePeople = random.nextInt(8) + 1;
        int maxArrivePeople = arrivePeople;     //当前电梯允许进入的人数，若全部人进入超重，则只允许进入正好满载的人数
        int lastCountPeople = countPeople;      //记录进入电梯前电梯内的人数
        countPeople += arrivePeople;
        if(currentFloor != 20) {
            OuterController.directionButton[2 * (currentFloor - 1)].setBackground(Color.WHITE);
        }
        if(currentFloor != 1) {
            OuterController.directionButton[2 * (currentFloor - 1) + 1].setBackground(Color.WHITE);
        }
        if(isOverWeight()) {
            JOptionPane.showMessageDialog(null, "超重", "警告", JOptionPane.WARNING_MESSAGE);
            maxArrivePeople = OVER_WEIGHT - lastCountPeople;
            countPeople = OVER_WEIGHT;
        }
        System.out.println(TimeDisplay.getTime() +": "+ id + "号电梯到达"+ currentFloor + "层，进入" + maxArrivePeople +"人");

        closeDoor();
        randomCmd[currentFloor-1] = 0;
    }

    public void leaveElevator() {
        openDoor();
        int leavePeople = random.nextInt(countPeople) + 1;
        countPeople -= leavePeople;
        System.out.println(TimeDisplay.getTime() +": "+ id + "号电梯到达"+ currentFloor + "层，离开电梯" + leavePeople +"人");
        closeDoor();
        randomCmd[currentFloor-1] = 0;
    }

    //获取电梯要到达的最高楼层的函数
    public int getMaxCmd(){
        int max = 1;
        for(int i=randomCmd.length - 1; i >= 0; i--){
            if(randomCmd[i] > 0){
                max = i + 1;
                break;
            }
        }
        return max;
    }

    //获取电梯要到达的最低楼层的函数
    public int getMinCmd(){
        int min = 1;
        for(int i = 0; i < randomCmd.length; i++){
            if(randomCmd[i] > 0){
                min = i + 1;
                break;
            }
        }
        return min;
    }

    //判断电梯是否超重的函数
    private boolean isOverWeight() {
        if (countPeople > HElevator.OVER_WEIGHT) {
            //System.out.println("进电梯" + enterPeople + "个人，超重");
            return true;
        }
        return false;
    }

    public static void main(String[] args){
        HElevator e1 = new HElevator(1);
        e1.setRandomCmd(1,20);
        HElevator e2 = e1;
        e2.setRandomCmd(1,10);
        int[] a = e1.getRandomCmd();
        System.out.println(a[1]);
    }
}